require('dotenv').config()
const axios = require('axios')
const chalk = require('chalk')

// 雪球API配置
const XUEQIU_API = 'https://xueqiu.com/service/v5/stock/screener/quote/list'
const USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'

// 筛选条件
const FILTERS = {
    // 振幅范围：10% ~ 15%
    MIN_AMPLITUDE: 8,
    MAX_AMPLITUDE: 15,
    // 市值范围：100亿 ~ 500亿
    MIN_MARKET_CAP: 100, // 单位：亿
    MAX_MARKET_CAP: 500  // 单位：亿
}

/**
 * 获取雪球Cookie
 * 雪球API需要有效的Cookie才能访问
 */
async function getXueqiuCookie() {
    try {
        const response = await axios.get('https://xueqiu.com', {
            headers: {
                'User-Agent': USER_AGENT
            }
        })

        // 从响应头中提取Cookie
        const cookies = response.headers['set-cookie']
        if (!cookies || cookies.length === 0) {
            throw new Error('无法获取雪球Cookie')
        }

        // 将Cookie数组转换为字符串
        return cookies.map(cookie => cookie.split(';')[0]).join('; ')
    } catch (error) {
        console.error(chalk.red('获取雪球Cookie失败:'), error.message)
        throw error
    }
}

/**
 * 获取股票列表
 * @param {string} cookie 雪球Cookie
 * @param {number} page 页码
 * @param {number} size 每页数量
 * @param {boolean} getCount 是否获取总数量
 */
async function fetchStocks(cookie, page = 1, size = 90, getCount = false) {
    try {
        // 构建请求参数
        const params = {
            page,
            size,
            order: 'desc',
            orderby: 'percent',
            order_by: 'percent',
            market: 'CN',
            type: 'sh_sz',
            // 筛选A股
            exchange: 'CN',
            industry: 'all',
            _: Date.now()
        }

        const response = await axios.get(XUEQIU_API, {
            params,
            headers: {
                'User-Agent': USER_AGENT,
                'Cookie': cookie,
                'Referer': 'https://xueqiu.com/hq'
            }
        })

        return response.data
    } catch (error) {
        console.error(chalk.red('获取股票列表失败:'), error.message)
        throw error
    }
}

/**
 * 筛选符合条件的股票
 * @param {Array} stocks 股票列表
 */
function filterStocks(stocks) {
    console.log('开始筛选股票', stocks.length)
    return stocks.filter(stock => {
        // 排除科创板和创业板股票
        if (stock.symbol.startsWith('SH688') || stock.symbol.startsWith('SZ300')) {
            return false
        }

        // 排除ST股票
        if (stock.name.includes('ST')) {
            return false
        }

        // 计算振幅: (最高价 - 最低价) / 昨收价 * 100
        const amplitude = ((stock.high - stock.low) / stock.last_close) * 100

        // 市值转换为亿元
        const marketCapInBillion = stock.market_capital / 100000000

        // 检查是否符合振幅和市值条件
        return (
            amplitude >= FILTERS.MIN_AMPLITUDE &&
            amplitude <= FILTERS.MAX_AMPLITUDE &&
            marketCapInBillion >= FILTERS.MIN_MARKET_CAP &&
            marketCapInBillion <= FILTERS.MAX_MARKET_CAP
        )
    })
}

/**
 * 打印股票信息
 * @param {Array} stocks 筛选后的股票列表
 */
function printStocks(stocks) {
    console.log(chalk.green('\n===== 股票列表 ====='))
    console.log(chalk.green(`共获取到 ${stocks.length} 只股票\n`))

    if (stocks.length === 0) {
        console.log(chalk.yellow('没有获取到任何股票数据'))
        return
    }

    // 表头
    console.log(
        chalk.cyan('代码'.padEnd(10)) +
        chalk.cyan('名称'.padEnd(12)) +
        chalk.cyan('当前价'.padEnd(10)) +
        chalk.cyan('涨跌幅'.padEnd(10)) +
        chalk.cyan('振幅'.padEnd(10)) +
        chalk.cyan('市值(亿)'.padEnd(12))
    )

    // 打印每只股票的信息
    stocks.forEach(stock => {
        const amplitude = ((stock.high - stock.low) / stock.last_close) * 100
        const marketCapInBillion = stock.market_capital / 100000000

        // 根据涨跌幅设置颜色
        const percentColor = stock.percent >= 0 ? chalk.red : chalk.green

        console.log(
            chalk.white(stock.symbol.padEnd(10)) +
            chalk.white(stock.name.padEnd(12)) +
            chalk.white(stock.current.toFixed(2).toString().padEnd(10)) +
            percentColor((stock.percent >= 0 ? '+' : '') + stock.percent.toFixed(2) + '%'.padEnd(10)) +
            chalk.yellow(amplitude.toFixed(2) + '%'.padEnd(10)) +
            chalk.white(marketCapInBillion.toFixed(2).toString().padEnd(12))
        )
    })
}

/**
 * 主函数
 */
async function main() {
    try {
        console.log(chalk.blue('开始获取符合假阴式洗盘条件的股票...'))

        // 获取雪球Cookie
        const cookie = await getXueqiuCookie()
        console.log(chalk.green('成功获取雪球Cookie'))

        // 获取股票列表 (多获取几页以确保覆盖足够的股票)
        let allStocks = []
        const totalPages = 10

        for (let page = 1; page <= totalPages; page++) {
            console.log(chalk.blue(`正在获取第 ${page}/${totalPages} 页股票数据...`))
            const data = await fetchStocks(cookie, page)

            if (data && data.data && data.data.list) {
                allStocks = allStocks.concat(data.data.list)
            } else {
                console.warn(chalk.yellow(`第 ${page} 页数据格式异常`))
            }

            // 简单的延迟，避免请求过于频繁
            await new Promise(resolve => setTimeout(resolve, 1000))
        }

        console.log(chalk.green(`共获取到 ${allStocks.length} 只股票`))

        // 直接打印所有股票，不进行筛选
        printStocks(allStocks)

    } catch (error) {
        console.error(chalk.red('程序执行出错:'), error)
    }
}

// 执行主函数
main()